package com.example.Paymodule;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.example.config.AlipayConfig;
import com.example.entity.StandardItem;
import com.example.entity.StandardOrder;
import com.example.mapper.OrderItemDao;
import com.example.mapper.OrdermDao;
import com.example.qrcode.QRCodeUtil;
import com.example.qrcode.QrCodeResponse;
import com.example.qrcode.QrResponse;
import com.example.result.BusinessException;
import com.example.result.ResultCodeEnum;
import com.example.util.GenerateNum;
import com.example.util.ParamsUtil;
import com.example.util.WebSocketPusher;
import com.example.vo.PayVom;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.ResourceUtils;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Service
public class AlipayService implements PayService {


    //创建一个日志记录器
    Logger logger = LoggerFactory.getLogger(AlipayService.class);
    @Autowired
    private AlipayConfig alipayConfig;

    @Resource
    private OrdermDao ordermDao;//查询订单的数据层

    @Resource
    private OrderItemDao orderitemDao;
    @Autowired
    private WebSocketPusher webSocketPusher;

  /* @Autowired
    private WebSocketServer WebSocketServer;*/


    @Override
    public byte[] alipay(PayVom payVom) throws Exception {
        /**
         * 1. 获取阿里客户端
         * 2. 获取阿里请求对象
         * 3. 设置请求参数
         * 4. 设置同步通知回调路径
         * 5. 设置异步通知回调路径
         */
        StandardOrder order=ordermDao.queryById(payVom.getOrderId());
        if(order==null){
            throw new BusinessException(ResultCodeEnum.SYSTEM_EXCEPTION);
        }
        //根据订单获取相关的商品信息
        List<StandardItem> orderItems = orderitemDao.queryByOrderId(order.getOrderId());
        //设置支付回调时可以在request中获取的参数
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderId", String.valueOf(order.getOrderId()));
        jsonObject.put("totalPrice", String.valueOf(order.getTotalPrice()));
        jsonObject.put("payMethod", payVom.getPayMethod());
       //处理订单项数据
        /*JSONArray itemsArray = new JSONArray();
        if (orderItems != null) {
            for (StandardItem item : orderItems) {
                if (item != null) {
                    JSONObject itemJson = new JSONObject();
                    itemJson.put("productId", item.getProductId());
                    itemJson.put("quantity", item.getQuantity());
                    itemJson.put("price", item.getPrice());
                    itemsArray.add(itemJson);
                }
            }
        }
        jsonObject.put("items", itemsArray);*/
        String params = jsonObject.toString();
        System.out.println("Params before setting to body: " + params);


        //设置支付参数
        String orderNumber = GenerateNum.generateOrder();//雪花算法生成随机不重复的订单号
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setBody(params);
        model.setTotalAmount( order.getTotalPrice().compareTo(BigDecimal.ZERO) == 0 ? "0.0" : order.getTotalPrice().toString());//对于lipay来说价格的属性为String类型
        model.setOutTradeNo(orderNumber);
        model.setSubject("onlineshopping");
        //获取响应二维码信息
        QrCodeResponse qrCodeResponse=qrcodePay(model);
        //制作二维码并且返回给前端，创建一个字节数组输出流，用于存储二维码图片的二进制数据。
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        String logopath="";
        logopath= ResourceUtils.getFile("classpath:favicon.png").getAbsolutePath();
        BufferedImage encode= QRCodeUtil.encode(qrCodeResponse.getQr_code(),logopath,true);
        //创建图片写入输出流
        ImageOutputStream imageOutputStream= ImageIO.createImageOutputStream(byteArrayOutputStream);
        //把二维码写入该输出流中
        ImageIO.write(encode,"JPEG",imageOutputStream);
        //关闭流，释放资源
        imageOutputStream.close();
        //把流转换成byte[]方便输出
        ByteArrayInputStream byteArrayInputStream =new ByteArrayInputStream(byteArrayOutputStream.toByteArray());

        return FileCopyUtils.copyToByteArray(byteArrayInputStream);

    }

    @Override
    public Boolean alipayCallback(HttpServletRequest request) throws Exception {
        try {
           logger.info("Request Content-Type: " + request.getContentType());
            Map<String, String> params = ParamsUtil.ParamstoMap(request);
            logger.info("callback parameter=========>" + params);
            System.out.println("the start of callback");
            String body1 = params.get("body");
            logger.info("transaction sequence number and transactiom information===========>", body1);
            JSONObject body = JSONObject.parseObject(body1);
            logger.info("Request Headers: " + Collections.list(request.getHeaderNames()));
            logger.info("Request Body: " + new String(request.getInputStream().readAllBytes(), StandardCharsets.UTF_8));

            //Integer userId = body.getString("userId");
            //String payMethon = body.getString("payMethon");
            String orderId = body.getString("orderId");

            // 如果回调数据中包含 orderId
            if (orderId != null) {
                System.out.println("支付成功，orderId: " + orderId);  // 确保 orderId 不是 null
                ordermDao.updateOrder(Integer.valueOf(orderId), "PAID");
                List<StandardItem> items=orderitemDao.queryByOrderId(Integer.valueOf(orderId));
                for(StandardItem item:items){
                    orderitemDao.updatedisplayStatus(item.getOrderItemsId(),"待商家确认");
                }
                // 发送 WebSocket 消息
              webSocketPusher.pushToUser(orderId,"支付成功");

            } else {
                logger.error("Order ID is missing in the callback");
                return false;
            }

        } catch (Exception e) {
            logger.error("Error occurred while processing Alipay callback", e);
            return false;
        }
        return true;
    }



    /**
     * 支付宝客户端发送支付请求获取支付二维码信息
     * */
    public QrCodeResponse qrcodePay(AlipayTradePrecreateModel model) throws Exception {
        //1.获取请求客户端
        AlipayClient alipayClient=getAlipayClient();

        //2.获取请求对象
        AlipayTradePrecreateRequest alipayRequest=new AlipayTradePrecreateRequest();

        //3.设置请求参数
        alipayRequest.setBizModel(model);
        alipayRequest.setNotifyUrl(alipayConfig.getNotify_url());
        alipayRequest.setReturnUrl(alipayConfig.getReturn_url());
        //4.发送请求到支付宝，获取响应
        AlipayTradePrecreateResponse execute=null;
        execute=alipayClient.execute(alipayRequest);
        //5.获取支付宝返回的json字符串
        String body=execute.getBody();//支付宝这个响应是带有字符串的吗？
        logger.info("QR code information for the request responseco===>"+body);
        //6.解析json响应，获取二维码信息，把json字符串换成java对象，换成java对象便于生成二维码的Java文件
        QrResponse qrResponse= JSON.parseObject(body,QrResponse.class);
        //最终返回二维码信息，前端就可以用它生成二维码，让用户扫码支付。
        return qrResponse.getAlipay_trade_precreate_response();
    }

    /**
     * 获取阿里客户端
     * 创建并返回一个AlipayClient 对象，用于调用 支付宝API进行支付操作
     * 调用支付宝API时，需要AlipayClient
     * */
    public AlipayClient getAlipayClient(){
        DefaultAlipayClient defaultAlipayClient=new DefaultAlipayClient(
                alipayConfig.getURL(),
                alipayConfig.getAPPID(),
                alipayConfig.getRSA_PRIVATE_KEY(),
                alipayConfig.getFORMAT(),
                alipayConfig.getCHARSET(),
                alipayConfig.getALIPAY_PUBLIC_KEY(),
                alipayConfig.getSIGNTYPE()
        );
        return defaultAlipayClient;
    }


}
